'use strict';
const crypto = require('crypto');
const WebSocket = require('ws');

const APP_ID = '2025579665';
const APP_KEY = 'DWaLmGYeXmNGggPa';

// 生成规范化查询字符串
function genCanonicalQueryString(params) {
    if (!params) return '';
    const sortedKeys = Object.keys(params).sort();
    const encodedParams = sortedKeys.map(key => {
        const value = params[key];
        // 根据文档，URL参数需要URLEncode
        return `${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`;
    });
    return encodedParams.join('&');
}

// 生成签名 (修正为Base64编码)
function genSignature(appKey, signingString) {
  const hmac = crypto.createHmac('sha256', appKey);
  hmac.update(signingString, 'utf-8');
  return hmac.digest('base64'); // <--- 修改这里，Base64编码
}

// 生成鉴权请求头 (根据文档和Python示例进一步优化)
function genSignHeaders(appId, appKey, method, uri, queryParams) {
  const nonce = Math.random().toString(36).substr(2, 8); // 生成8位随机字符串
  const timestamp = Math.floor(Date.now() / 1000).toString(); // 秒级时间戳

  // 合并URL参数，生成规范化query string
  const allQueryParams = { 
      ...
      queryParams, // 确保所有传递进来的URL参数都被包含
      system_time: timestamp, // 文档和示例表明system_time是URL参数且需参与签名
      user_id: crypto.randomBytes(16).toString('hex') // 文档和示例表明user_id是URL参数且需参与签名
  };

  // 生成规范化查询字符串，用于签名和构建URL
  const canonical_query_string = genCanonicalQueryString(allQueryParams);
  console.log('Canonical Query String:', canonical_query_string); // 添加日志

  // 构建Signed Headers String，用于签名
  const signed_headers_string =
    `x-ai-gateway-app-id:${appId}\n` +
    `x-ai-gateway-timestamp:${timestamp}\n` +
    `x-ai-gateway-nonce:${nonce}`;
  console.log('Signed Headers String:', signed_headers_string); // 添加日志

  // 构建待签名的原始字符串
  const signing_string = `${method.toUpperCase()}\n` +
                           `${uri}\n` +
                           `${canonical_query_string}\n` +
                           `${appId}\n` +
                           `${timestamp}\n` +
                           `${signed_headers_string}`;
  console.log('Signing String:', signing_string); // 添加日志

  // 计算签名
  const signature = genSignature(appKey, signing_string);

  // 构建最终的Headers对象
  const headers = {
    'X-AI-GATEWAY-APP-ID': appId,
    'X-AI-GATEWAY-TIMESTAMP': timestamp,
    'X-AI-GATEWAY-NONCE': nonce,
    'X-AI-GATEWAY-SIGNED-HEADERS': "x-ai-gateway-app-id;x-ai-gateway-timestamp;x-ai-gateway-nonce",
    'X-AI-GATEWAY-SIGNATURE': signature,
  };
  
  // 额外返回canonical_query_string，方便在main函数中构建最终的WebSocket URL
  headers._canonicalQueryString = canonical_query_string;

  return headers;
}

exports.main = async (event, context) => {
  console.log('云函数 ttsProxy 被调用，事件参数:', event);
  return new Promise((resolve, reject) => {
    const { text, vcn = 'yige' } = event;
    if (!text) {
        console.error('TTS 输入文本为空');
        return reject({ code: 400, message: '输入文本不能为空' });
    }
    console.log('待合成文本:', text);

    // 使用genSignHeaders生成签名头和canonical_query_string
    const signatureHeaders = genSignHeaders(APP_ID, APP_KEY, 'GET', '/tts', {
        engineid: 'short_audio_synthesis_jovi',
        // system_time 和 user_id 现在在genSignHeaders内部生成并包含在canonical_query_string中
        model: 'unknown',
        product: 'unknown',
        package: 'unknown',
        client_version: 'unknown',
        system_version: 'unknown',
        sdk_version: 'unknown',
        android_version: 'unknown'
    });

    // 从返回结果中获取canonical_query_string来构建URL
    const canonical_query_string_for_url = signatureHeaders._canonicalQueryString;

    // 移除Header中用于内部传递的字段
    delete signatureHeaders._canonicalQueryString;

    const headers = signatureHeaders; // 使用生成的完整Header对象

    // 使用canonical_query_string构建完整的WebSocket URL
    const wsUrl = `wss://api-ai.vivo.com.cn/tts?${canonical_query_string_for_url}`; // <--- URL现在只拼接canonical_query_string
    console.log('WebSocket URL:', wsUrl); // 添加日志
    console.log('WebSocket Headers:', headers);

    const ws = new WebSocket(wsUrl, { headers });

    let audioBuffers = [];

    ws.on('open', () => {
      console.log('WebSocket 连接已打开');
      ws.send(JSON.stringify({
        aue: 0,
        auf: "audio/L16;rate=24000",
        vcn,
        speed: 50,
        volume: 50,
        text: Buffer.from(text, 'utf8').toString('base64'),
        encoding: "utf8",
        reqId: Date.now()
      }));
      console.log('WebSocket 发送文本数据');
    });

    ws.on('message', (data) => {
      console.log('WebSocket 收到消息');
      const msg = JSON.parse(data);
      console.log('收到的消息:', msg);
      if (msg.error_code === 0 && msg.data && msg.data.audio) {
        audioBuffers.push(Buffer.from(msg.data.audio, 'base64'));
        if (msg.data.status === 2) {
          console.log('收到最后一片音频数据，关闭WebSocket');
          ws.close();
        }
      } else if (msg.error_code !== 0) {
        console.error('TTS服务返回错误:', msg);
        ws.close();
        reject({ error: msg.error_msg });
      }
    });

    ws.on('close', (code, reason) => {
      console.log(`WebSocket 连接已关闭，代码: ${code}, 原因: ${reason}`);
      const pcmBuffer = Buffer.concat(audioBuffers);
      console.log('TTS云函数合成音频长度:', pcmBuffer.length);
      resolve({
        code: 0,
        msg: 'success',
        data: pcmBuffer.length > 0 ? pcmBuffer.toString('base64') : null
      });
    });

    ws.on('error', (err) => {
      console.error('WebSocket 发生错误:', err);
      reject({ error: err.message });
    });
  });
};